<?php
defined( 'IN_DICE' ) or die( 'Access Error!' );

class control {

  public $check = 0; //数据验证通过结果
  public $error = 0; //此次请求的成功标志,1为成功,默认不成功
  public $msg = ''; //此次请求的描述
  public $ret = array(); //此次请求真正返回的数据
  public $flag = 1; //标志从服务端返回

  public $uid = 0; //请求用户ID
  public $pfid = 0; //请求用户平台ID
  public $usid = 0; //请求用户子平台(站点)ID
  public $param = array(); //此次请求的真正参数
  public $olkey = '0'; //此次请求的在线表中的olkey
  public $lang = 0; //此次请求的用户的语言
  public $time = 0; //请求的时间
  public $sign = ''; //此次请求的数据签名

  public $puid = ''; //平台方的用户ID

  private $chash = 'fnmrijfiowajr3892uvfmklfm3849urfmks'; //验证登陆cookie的字符串

  function __construct() {
    $pflag = func::input( 'p' ); //平台pkey
    $pflag = str_ireplace( '/', '', $pflag );
    if( !$pflag ) func::showerr('Platform Ini Error!');
    all::$cfg['pflag'] = in_array( $pflag, all::$cfg['openpf'] ) ? $pflag : 'renren';
    func::smarty()->compile_dir .= $pflag;
    
    all::$aOut['apiid'] = model::platform()->apiid;
    all::$aOut['apiurl'] = model::platform()->apiurl;
    all::$aOut['apikey'] = model::platform()->apikey;

    all::loadlang( all::$cfg['lang'] ); //设置系统默认语言
    //$this->_loadtooldesc();//加载道具
    
    $this->_checklogin(); //检查cookie
  }

  /**
   * 验证客户端传过来的数据,测试环境不验证
   * @param array $req 客户端传过来的原始数据
   * @param int $level 验证等级.0,验证sig与在线,time.1不可以房间内.2防重复
   * @return int 验证结果,1成功 0失败或不在线,-1在房间内,-2重复请求太多太快
   */
  public function auth( $req, $level ) {
    if( PRODUCT_ENV === false ) {
      $this->_getData( $req );
      return 1;
    }
    $level = uint( $level );
    $sign = $req['sign'];
    unset( $req['sign'] );
    $sSig = $this->_joins( $req, (string)$req['olkey'] );
    $flag = ( strcmp( $sign, md5( $sSig ) ) === 0 ? 1 : 0 );
    if( ! $flag ) {
      model::logs()->debug( $req, 'error.txt');
      model::logs()->debug( md5( $sSig ) . '|' . $sign . '|', 'error.txt');
    }
    $flag && $flag = model::online()->auth( $req['uid'], $req['olkey'], $level ) ? $flag : -$level; //在线有效性验证及验证是否在桌子里面
    if( $flag && $level == 2 ) { //防重复刷新
      $flag = model::online()->limit( $req['uid'], 0, $sign ) ? $flag : -$level;
    }
    if( $flag ) { //验证通过,获得请求中包含的参数
      $this->_getData( $req );
    }
    
    return $flag;
  }

  /**
   * 确认flash传过来的数据OK,并将flash请求中的参数添加给对象
   *
   * @param array $req
   * @return null
   */
  private function _getData( $req ) {
    list( $this->uid, $this->pfid, $this->usid, $this->param, $this->olkey, $this->lang, $this->time, $this->sign ) =
    array( $req['uid'], $req['pfid'], $req['usid'], $req['param'], $req['olkey'], $req['lang'], $req['time'], $req['sign'], );
    if( $this->uid > 0 ) {
      $this->check = 1;
      all::loadlang( $this->lang ); //加载语言
    }
  }

  /**
   * 制作返回给flash的参数
   * @param mixd $ret 返回的结果
   * @return array
   */
  public function genRes( $ret = array() ) {
    $res['check'] = $this->check; //数据验证通过结果
    $res['error'] = $this->error; //请求是否成功,1成功,其它:不成功
    $res['msg'] = $this->msg; //此次请求的描述文字
    $res['time'] = time();  //此次请求发生的时间
    $res['ret'] = $ret; //此次返回真正的数据
    $res['flag'] = $this->flag;  //标志从服务端返回
    return $res;
  }
  
  /**
   * 私有方法来组合数组对象
   *
   * @param array $arg
   * @param string $olkey
   * @return string
   */
  public function _joins( $arg, $olkey ) {
    $str = 'AS';
    if ( !is_object( $arg ) ) {
      if( is_null( $arg) || is_bool( $arg ) ) {
        $str .= '';
      } else if ( is_string( $arg ) || is_numeric( $arg ) ) {
        $str .= 'X' . $olkey . $arg;
      } else {
        ksort( $arg, SORT_STRING );
        foreach( $arg as $key => $value ) {
          $str .= ( $key . '=' . $this->_joins( $value, $olkey ) );
        }
      }
    }
    return $str;
  }
  
  /**
   * 获得flash初始化所需要的参数
   *
   * @param array $aU
   * @param string $olkey
   */
  public function getSwfVars( $aU, $olkey ) {
    $aFlash = array(
      'uid' => $aU['uid'],
      'pfid' => $aU['pfid'],
      'usid' => $aU['usid'],
      'lang' => isset( $aU['lang'] ) ? $aU['lang'] : all::$cfg['lang'],
      'olkey' => $olkey,
      'tid' => isset( $_GET['tid'] ) ? $_GET['tid'] : 0, //断线重连用的
      'uface' => model::member()->getHomePage( $aU['puid'], $aU['pfid'] ),
      'baseurl' => all::$aOut['baseurl'], //web根地址
      'gwurl' => all::$cfg['gateway'] . ( isset( $_REQUEST['debug'] ) ? "&debug=".S('debug') : '' ), //gateway地址
      'swfurl' => all::$cfg['swfurl'], //flash的加载根地址
      'xmlurl' => all::$aOut['baseurl'] . 'data/', //xml的加载根地址
      'imgurl' => all::$aOut['imgurl'], //图片请求的根地址
      'xver' => json_encode( all::$cfg['xver'] ), //xml版本号json字符串
      'fver' => json_encode( all::$cfg['fver'] ), //flash版本号json字符串
    );

    return $aFlash;
  }

  /**
   * 检查用户的游戏登陆情况
   *
   * @return int
   */
  public function _checklogin() {
    $return = -3;
    $cname = 'nbauth'.model::platform()->pfid; //cookie的名称
    $sC = func::input( $cname, 's', 'COOKIE' );
    $ip = func::getclientip();
    if ( strlen( $sC ) > 40 ) {
      if( count(explode( ',', $sC ) ) < 7 ) {
        return $return;
      }
      list( $aC['uid'], $aC['puid'], $aC['pfid'], $aC['lang'], $aC['time'], $aC['ip'], $sign ) = explode( ',', $sC );
      $sC = "{$aC['uid']},{$aC['puid']},{$aC['pfid']},{$aC['lang']},{$aC['time']},{$ip}";
      if ( $sign == sha1( $sC . $this->chash ) && $aC['ip'] == $ip ) {
        list( $this->uid, $this->puid, $this->pfid, $this->lang, $this->time ) = array( $aC['uid'], $aC['puid'], $aC['pfid'], $aC['lang'], $aC['time'] );
        return 1;
      }

      $return = -2; //验证失败
      if ( $aC['ip'] != $ip ) {
        $return = -1; //ip已切换，不承认此cookie
      }
    }
    return $return;
  }

  /**
   * 设置用户登陆情况
   *
   * @return null
   */
  public function _setlogin() {
    $t = time();
    $ip = func::getclientip();
    $aC = array( all::$aU['uid'], all::$aU['puid'], all::$aU['pfid'], isset( all::$aU['lang'] ) ? all::$aU['lang'] : all::$cfg['lang'], $t, $ip );//uid,puid,pfid,lang,time,ip,sign
    $sC = implode( ',', $aC );
    $sign = sha1( $sC . $this->chash );
    $sC .= ",$sign";
    setcookie( 'diceauth'.model::platform()->pfid, $sC );
  }

  /**
   * 检查当前登陆用户是不是当前的cookie里面的用户,如果不是,则清除相应的登陆信息
   * @param string $puid 平台ID
   * @return null
   */
  public function _checkuser( $puid ) {
    $cname = 'diceauth'.model::platform()->pfid; //cookie的名称
    if( strlen( $puid ) && $this->puid != $puid ) {
      setcookie($cname, '', -3600 );
      $this->uid = $this->puid = $this->pfid = 0;
    }
  }

}